﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Main
{
    public partial class FormServer : Form
    {

        private List<string> hosts = new List<string>();
        //发送数据对话框
        private Sending sending = new Sending();

        private MainServer mainServer;


        public FormServer()
        {
            InitializeComponent();
        }

        private void FormServer_Load(object sender, EventArgs e)
        {

            mainServer = MainServer.Instance();
            //注册mainServer事件
            mainServer.OnServerStarted += MainServer_OnServerStarted;
            mainServer.OnServerClosed += MainServer_OnServerClosed;
            mainServer.OnClientConnected += MainServer_OnClientConnected;
            mainServer.OnClientUpdateUI += MainServer_OnClientUpdateUI;
            mainServer.OnSendingStatusChanged += MainServer_OnSendingStatusChanged;
            mainServer.OnClientLostConnection += MainServer_OnClientLostConnection;

            this.InitHostCmbox();
            this.cmbThreadNum.SelectedIndex = 0;
        }

        /// <summary>
        /// 客户端关闭
        /// </summary>
        /// <param name="instance"></param>
        /// <param name="client"></param>
        private void MainServer_OnClientLostConnection(MainServer instance, ClientHolder client)
        {
            this.Invoke(new Action(() => {
                string socketHandle = client.Socket.Handle.ToString();
                if (this.listView1.Items.ContainsKey(socketHandle))
                {
                    ListViewItem item = this.listView1.Items[socketHandle];
                    this.listView1.Items.Remove(item);
                }
            }));
            
        }


        /// <summary>
        /// 发送指令的进度更新
        /// </summary>
        /// <param name="current"></param>
        /// <param name="max"></param>
        private void MainServer_OnSendingStatusChanged(int current, int max)
        {

            if(sending != null)
            {
                sending.Invoke(new Action(() =>
                {
                    sending.SendingProgress.Maximum = max;
                    sending.SendingProgress.Value = current;
                    if (max == current)
                    {
                        sending.Hide();
                    }
                }));
                
            }
        }



        /// <summary>
        /// 更新界面数据状态
        /// </summary>
        /// <param name="instance"></param>
        /// <param name="client"></param>
        private void MainServer_OnClientUpdateUI(MainServer instance, ClientHolder client)
        {
            this.Invoke(new Action(() =>
            {
                string socketHandle = client.Socket.Handle.ToString();
                string ID = client.ID;
                if(ID == string.Empty)
                {
                    return;
                }

                ListViewItem item = null;
                if (this.listView1.Items.ContainsKey(socketHandle))
                {
                    item = this.listView1.Items[socketHandle];
                }
                else
                {
                    item = new ListViewItem();
                    item.Name = socketHandle;
                    item.Text = client.ID;
                    
                    ListViewItem.ListViewSubItem item2 = new ListViewItem.ListViewSubItem();
                    item2.Name = "ConnectionStatus";
                    item2.Text = client.ConnectionStatusText;
                    ListViewItem.ListViewSubItem item3 = new ListViewItem.ListViewSubItem();
                    item3.Name = "ThreadNum";
                    item3.Text = client.ThreadStatus.ToString();
                    ListViewItem.ListViewSubItem item4 = new ListViewItem.ListViewSubItem();
                    item4.Name = "ThreadStatus";
                    item4.Text = client.ThreadStatus.ToString();
                    ListViewItem.ListViewSubItem item5 = new ListViewItem.ListViewSubItem();
                    item5.Name = "Process";
                    item5.Text = client.CurrentCode + "/" + client.CodeTo;
                    ListViewItem.ListViewSubItem item6 = new ListViewItem.ListViewSubItem();
                    item6.Name = "Result";
                    item6.Text = client.Result;
                    item.SubItems.AddRange(new ListViewItem.ListViewSubItem[] {item2,item3,item4,item5,item6 });
                    this.listView1.Items.Add(item);
                }
                
                if (item != null)
                {
                    item.Text = client.ID;
                    item.SubItems["ThreadNum"].Text = client.ThreadNum.ToString();
                    item.SubItems["ThreadStatus"].Text = client.ThreadStatus.ToString();
                    item.SubItems["Process"].Text = client.CurrentCode + "/" + client.CodeTo;
                    item.SubItems["Result"].Text = client.Result;
                }
            }));
            
        }

        private void MainServer_OnClientConnected(MainServer instance, System.Net.Sockets.Socket socket)
        {
            Log("客户端连接丢失");
        }

        private void MainServer_OnServerClosed()
        {
            Log("主控服务已经关闭");
        }

        private void MainServer_OnServerStarted()
        {
            Log("主控服务启动成功");
        }

        private void InitHostCmbox()
        {
            this.GetAllLocalHosts();
            for (int i = 0; i < this.hosts.Count; i++)
            {
                this.cmbHost.Items.Add(this.hosts[i]);
            }
            this.cmbHost.SelectedIndex = 0;
        }

        private List<string> GetAllLocalHosts()
        {
            string hostName = Dns.GetHostName();
            System.Net.IPAddress[] addressList = Dns.GetHostAddresses(hostName);
            foreach (IPAddress ip in addressList)
            {
                string _temp_ip = ip.MapToIPv4().ToString();
                string[] ipstr = _temp_ip.Split('.');
                if (ipstr[0] == "127" || ipstr[0] == "10" || ipstr[0] == "172")
                {
                    continue;
                }
                else
                {
                    string temp = hosts.Where(s => s == _temp_ip).FirstOrDefault();
                    if (temp == null)
                    {
                        hosts.Add(_temp_ip);
                    }
                }
            }
            return hosts;
        }

        private void btnStartServer_Click(object sender, EventArgs e)
        {

            string host = this.cmbHost.Text;
            int port = Int32.Parse(this.txtPort.Text);

            mainServer.start(host, port);
        }


        private void Log(string str)
        {
            this.txtLog.Invoke(new Action(() =>
            {
                if (this.txtLog.Lines.Length > 5000)
                {
                    this.txtLog.Clear();
                }
                DateTime dt = System.DateTime.Now;
                StringBuilder sb = new StringBuilder();
                sb.Append("[");
                sb.Append(dt.ToString("t"));
                sb.Append("]");
                sb.Append(" ");
                sb.Append(str);
                sb.Append("\r\n");
                this.txtLog.AppendText(sb.ToString());
            }));

        }

        private void btnFenPeiCmd_Click(object sender, EventArgs e)
        {

        }

        private void btnSettingCmd_Click(object sender, EventArgs e)
        {
            sending.SendingProgress.Minimum = 0;
            sending.SendingProgress.Value = 0;
            
            

            CmdData cmdData = new CmdData();
            cmdData.Cmd = "SETTING";
            mainServer.sendCmd(cmdData);

            sending.StartPosition = FormStartPosition.CenterScreen;
            sending.ShowDialog();
        }
    }
}
